import sys
import os
import json
import datetime
import vlc
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
                             QPushButton, QSlider, QLabel, QFileDialog, QListWidget, QSplitter,
                             QStatusBar, QStyle, QMessageBox)
from PyQt5.QtCore import Qt, QUrl, QTimer, QStandardPaths
from PyQt5.QtGui import QIcon, QPalette, QColor


class VLCMediaPlayer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("VLC Media Player")
        self.setGeometry(100, 100, 900, 600)

        # 初始化VLC
        self.instance = vlc.Instance("--no-xlib")
        self.player = self.instance.media_player_new()

        # 初始化UI
        self.init_ui()

        # 加载历史记录
        self.history_file = self.get_history_file_path()
        self.play_history = []
        self.load_history()

        # 设置样式
        self.set_dark_theme()

        # 设置初始状态
        self.update_buttons()

        # 设置音量
        self.player.audio_set_volume(80)

        # 创建定时器更新进度
        self.position_timer = QTimer()
        self.position_timer.timeout.connect(self.update_position)
        self.position_timer.start(200)  # 每200毫秒更新一次

    def init_ui(self):
        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # 主布局
        main_layout = QHBoxLayout(central_widget)

        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        main_layout.addWidget(splitter)

        # 左侧面板 - 播放列表和历史记录
        left_panel = QWidget()
        left_layout = QVBoxLayout(left_panel)
        left_layout.setContentsMargins(0, 0, 0, 0)

        # 播放列表
        self.playlist_widget = QListWidget()
        self.playlist_widget.itemDoubleClicked.connect(self.play_selected_item)
        self.playlist_widget.setMinimumWidth(250)
        left_layout.addWidget(QLabel("播放列表:"))
        left_layout.addWidget(self.playlist_widget)

        # 播放历史
        self.history_widget = QListWidget()
        self.history_widget.itemDoubleClicked.connect(self.play_from_history)
        self.history_widget.setMinimumWidth(250)
        left_layout.addWidget(QLabel("播放历史:"))
        left_layout.addWidget(self.history_widget)

        # 右侧面板 - 视频和控件
        right_panel = QWidget()
        right_layout = QVBoxLayout(right_panel)
        right_layout.setContentsMargins(0, 0, 0, 0)

        # 视频显示区域 - 使用QWidget作为VLC视频容器
        self.video_container = QWidget()
        self.video_container.setMinimumSize(640, 360)
        self.video_container.setStyleSheet("background-color: black;")
        right_layout.addWidget(self.video_container)

        # 进度条
        self.position_slider = QSlider(Qt.Horizontal)
        self.position_slider.setRange(0, 1000)  # 使用0-1000范围
        self.position_slider.sliderMoved.connect(self.set_position)
        right_layout.addWidget(self.position_slider)

        # 时间标签
        time_layout = QHBoxLayout()
        self.time_label = QLabel("00:00 / 00:00")
        self.time_label.setAlignment(Qt.AlignCenter)
        time_layout.addWidget(self.time_label)
        right_layout.addLayout(time_layout)

        # 控制按钮
        control_layout = QHBoxLayout()

        # 打开文件按钮
        self.open_button = QPushButton("打开文件")
        self.open_button.clicked.connect(self.open_file)
        control_layout.addWidget(self.open_button)

        # 播放按钮
        self.play_button = QPushButton()
        self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
        self.play_button.clicked.connect(self.play_pause)
        control_layout.addWidget(self.play_button)

        # 停止按钮
        self.stop_button = QPushButton()
        self.stop_button.setIcon(self.style().standardIcon(QStyle.SP_MediaStop))
        self.stop_button.clicked.connect(self.stop)
        control_layout.addWidget(self.stop_button)

        # 上一首按钮
        self.prev_button = QPushButton()
        self.prev_button.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipBackward))
        self.prev_button.clicked.connect(self.play_previous)
        control_layout.addWidget(self.prev_button)

        # 下一首按钮
        self.next_button = QPushButton()
        self.next_button.setIcon(self.style().standardIcon(QStyle.SP_MediaSkipForward))
        self.next_button.clicked.connect(self.play_next)
        control_layout.addWidget(self.next_button)

        # 音量控制
        self.volume_slider = QSlider(Qt.Horizontal)
        self.volume_slider.setRange(0, 100)
        self.volume_slider.setValue(80)
        self.volume_slider.setFixedWidth(100)
        self.volume_slider.valueChanged.connect(self.set_volume)
        control_layout.addWidget(QLabel("音量:"))
        control_layout.addWidget(self.volume_slider)

        # 清空历史按钮
        self.clear_history_button = QPushButton("清空历史")
        self.clear_history_button.clicked.connect(self.clear_history)
        control_layout.addWidget(self.clear_history_button)

        right_layout.addLayout(control_layout)

        # 添加面板到分割器
        splitter.addWidget(left_panel)
        splitter.addWidget(right_panel)
        splitter.setSizes([250, 650])

        # 状态栏
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage("就绪")

    def set_dark_theme(self):
        # 设置深色主题
        dark_palette = QPalette()
        dark_palette.setColor(QPalette.Window, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.WindowText, Qt.white)
        dark_palette.setColor(QPalette.Base, QColor(25, 25, 25))
        dark_palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.ToolTipBase, Qt.white)
        dark_palette.setColor(QPalette.ToolTipText, Qt.white)
        dark_palette.setColor(QPalette.Text, Qt.white)
        dark_palette.setColor(QPalette.Button, QColor(53, 53, 53))
        dark_palette.setColor(QPalette.ButtonText, Qt.white)
        dark_palette.setColor(QPalette.BrightText, Qt.red)
        dark_palette.setColor(QPalette.Link, QColor(42, 130, 218))
        dark_palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
        dark_palette.setColor(QPalette.HighlightedText, Qt.black)

        self.setPalette(dark_palette)

        # 设置按钮样式
        button_style = """
            QPushButton {
                background-color: #353535;
                border: 1px solid #555;
                border-radius: 4px;
                padding: 5px;
                min-width: 80px;
            }
            QPushButton:hover {
                background-color: #454545;
            }
            QPushButton:pressed {
                background-color: #252525;
            }
        """
        self.open_button.setStyleSheet(button_style)
        self.play_button.setStyleSheet(button_style)
        self.stop_button.setStyleSheet(button_style)
        self.prev_button.setStyleSheet(button_style)
        self.next_button.setStyleSheet(button_style)
        self.clear_history_button.setStyleSheet(button_style)

        # 设置列表样式
        list_style = """
            QListWidget {
                background-color: #252525;
                color: white;
                border: 1px solid #444;
            }
            QListWidget::item:selected {
                background-color: #2a82da;
                color: white;
            }
        """
        self.playlist_widget.setStyleSheet(list_style)
        self.history_widget.setStyleSheet(list_style)

        # 设置滑块样式
        slider_style = """
            QSlider::groove:horizontal {
                border: 1px solid #444;
                height: 8px;
                background: #353535;
                margin: 2px 0;
            }
            QSlider::handle:horizontal {
                background: #2a82da;
                border: 1px solid #444;
                width: 18px;
                margin: -4px 0;
                border-radius: 4px;
            }
            QSlider::sub-page:horizontal {
                background: #2a82da;
            }
        """
        self.position_slider.setStyleSheet(slider_style)
        self.volume_slider.setStyleSheet(slider_style)

    def open_file(self):
        # 打开文件对话框
        file_dialog = QFileDialog()
        file_dialog.setFileMode(QFileDialog.ExistingFiles)
        file_dialog.setNameFilter(
            "媒体文件 (*.mp3 *.mp4 *.wav *.avi *.mkv *.flac *.mov *.wmv *.ogg *.m4a *.aac *.flv *.webm *.3gp *.wma *.mpg *.mpeg *.ts *.rmvb *.asf *.dv *.swf *.mxf)")

        if file_dialog.exec_():
            files = file_dialog.selectedFiles()
            for file in files:
                # 获取绝对路径
                abs_path = os.path.abspath(file)

                # 添加到播放列表
                item_text = os.path.basename(abs_path)
                self.playlist_widget.addItem(item_text)
                self.playlist_widget.item(self.playlist_widget.count() - 1).setToolTip(abs_path)

                # 如果是第一个文件，自动播放
                if self.playlist_widget.count() == 1:
                    self.play_media(abs_path)

    def play_selected_item(self):
        # 播放选中的播放列表项
        selected_items = self.playlist_widget.selectedItems()
        if selected_items:
            file_path = selected_items[0].toolTip()
            self.play_media(file_path)

    def play_media_by_index(self, index):
        # 根据索引播放媒体
        if 0 <= index < self.playlist_widget.count():
            file_path = self.playlist_widget.item(index).toolTip()
            self.play_media(file_path)

    def play_previous(self):
        # 播放上一首
        if self.playlist_widget.count() > 0:
            current_index = self.playlist_widget.currentRow()
            if current_index == -1:
                current_index = 0
            else:
                current_index = (current_index - 1) % self.playlist_widget.count()

            self.playlist_widget.setCurrentRow(current_index)
            self.play_media_by_index(current_index)

    def play_next(self):
        # 播放下一首
        if self.playlist_widget.count() > 0:
            current_index = self.playlist_widget.currentRow()
            if current_index == -1:
                current_index = 0
            else:
                current_index = (current_index + 1) % self.playlist_widget.count()

            self.playlist_widget.setCurrentRow(current_index)
            self.play_media_by_index(current_index)

    def play_media(self, file_path):
        """使用VLC播放媒体文件"""
        try:
            if os.path.exists(file_path):
                # 设置视频输出窗口
                if sys.platform == "win32":
                    # Windows系统
                    self.player.set_hwnd(int(self.video_container.winId()))
                elif sys.platform == "darwin":
                    # macOS系统
                    self.player.set_nsobject(int(self.video_container.winId()))
                else:
                    # Linux系统
                    self.player.set_xwindow(int(self.video_container.winId()))

                # 创建媒体对象
                media = self.instance.media_new(file_path)
                self.player.set_media(media)

                # 播放媒体
                self.player.play()

                # 添加到历史记录
                self.add_to_history(file_path)
                self.status_bar.showMessage(f"正在播放: {os.path.basename(file_path)}")

                # 更新按钮状态
                self.update_buttons()
            else:
                QMessageBox.critical(self, "错误", f"文件不存在:\n{file_path}")
        except Exception as e:
            error_msg = f"播放错误: {str(e)}"
            self.status_bar.showMessage(error_msg)
            QMessageBox.critical(self, "播放错误", error_msg)

    def play_pause(self):
        # 播放/暂停切换
        if self.player.is_playing():
            self.player.pause()
        else:
            if self.player.get_media() is None:
                # 如果没有媒体，尝试播放当前选中的项目
                self.play_selected_item()
            else:
                self.player.play()

        # 更新按钮状态
        self.update_buttons()

    def stop(self):
        # 停止播放
        self.player.stop()
        self.update_buttons()
        self.status_bar.showMessage("已停止")

    def set_position(self, position):
        # 设置播放位置 (0-1000)
        if self.player.is_playing():
            media_length = self.player.get_length()
            if media_length > 0:
                # 转换为毫秒
                new_position = int(position / 1000 * media_length)
                self.player.set_time(new_position)

    def update_position(self):
        # 更新位置滑块
        if self.player.is_playing():
            media_length = self.player.get_length()
            current_time = self.player.get_time()

            if media_length > 0:
                # 计算进度百分比 (0-1000)
                position_percent = int(current_time / media_length * 1000)
                self.position_slider.setValue(position_percent)

                # 更新时间标签
                current_time_str = self.format_time(current_time)
                total_time_str = self.format_time(media_length)
                self.time_label.setText(f"{current_time_str} / {total_time_str}")

                # 更新状态栏
                percent = (current_time / media_length) * 100
                self.status_bar.showMessage(f"播放中 - {percent:.1f}% 完成")

    def set_volume(self, volume):
        # 设置音量 (0-100)
        self.player.audio_set_volume(volume)

    def format_time(self, milliseconds):
        # 格式化时间 (毫秒 -> HH:MM:SS)
        seconds = milliseconds // 1000
        hours = seconds // 3600
        minutes = (seconds % 3600) // 60
        seconds = seconds % 60

        if hours > 0:
            return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
        else:
            return f"{minutes:02d}:{seconds:02d}"

    def update_buttons(self):
        # 更新按钮状态
        if self.player.is_playing():
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPause))
            self.status_bar.showMessage("播放中")
        else:
            self.play_button.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay))
            if self.player.get_media() is not None:
                self.status_bar.showMessage("已暂停")

    def get_history_file_path(self):
        # 获取历史记录文件路径
        app_data_path = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
        if not app_data_path:
            # 如果无法获取标准路径，使用用户主目录下的自定义目录
            app_data_path = os.path.join(os.path.expanduser("~"), ".vlc_media_player")

        if not os.path.exists(app_data_path):
            os.makedirs(app_data_path)
        return os.path.join(app_data_path, "media_player_history.json")

    def load_history(self):
        # 加载历史记录
        try:
            if os.path.exists(self.history_file):
                with open(self.history_file, 'r', encoding='utf-8') as f:
                    self.play_history = json.load(f)
                    self.update_history_list()
        except Exception as e:
            print(f"加载历史记录出错: {e}")

    def save_history(self):
        # 保存历史记录
        try:
            with open(self.history_file, 'w', encoding='utf-8') as f:
                json.dump(self.play_history, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存历史记录出错: {e}")

    def add_to_history(self, file_path):
        # 添加到历史记录
        file_name = os.path.basename(file_path)
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # 检查是否已存在
        for item in self.play_history:
            if item["path"] == file_path:
                item["last_played"] = timestamp
                self.update_history_list()
                self.save_history()
                return

        # 添加到历史记录
        self.play_history.insert(0, {
            "name": file_name,
            "path": file_path,
            "last_played": timestamp
        })

        # 限制历史记录数量
        if len(self.play_history) > 20:
            self.play_history = self.play_history[:20]

        # 更新列表并保存
        self.update_history_list()
        self.save_history()

    def update_history_list(self):
        # 更新历史记录列表
        self.history_widget.clear()
        for item in self.play_history:
            self.history_widget.addItem(f"{item['name']} ({item['last_played']})")
            self.history_widget.item(self.history_widget.count() - 1).setToolTip(item["path"])

    def play_from_history(self):
        # 从历史记录播放
        selected_items = self.history_widget.selectedItems()
        if selected_items:
            index = self.history_widget.row(selected_items[0])
            if 0 <= index < len(self.play_history):
                self.play_media(self.play_history[index]["path"])

    def clear_history(self):
        # 清空历史记录
        reply = QMessageBox.question(self, '确认',
                                     '确定要清空播放历史记录吗？',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.play_history = []
            self.history_widget.clear()
            self.save_history()

    def closeEvent(self, event):
        # 关闭窗口时停止播放并保存历史记录
        self.player.stop()
        self.save_history()
        event.accept()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")

    # 设置应用程序图标
    if hasattr(QStyle, 'SP_MediaPlay'):
        app.setWindowIcon(QIcon(app.style().standardIcon(QStyle.SP_MediaPlay)))

    player = VLCMediaPlayer()
    player.show()
    sys.exit(app.exec_())